importlib 模块: 图像处理模块

1. PIL的安装

pip3 install pillow -i https://pypi.douban.com/simple # 使用豆瓣的镜像

2. Image

  • 生成一个纯色背景图片对象

  • 语法: Image.new(mode='模式', size=尺寸, color=RGB色值 或 颜色的英文单词) -> Image.new('RGB', (245, 34), (255, 255, 0))

img_obj = Image.new('RGB', (245, 34), get_random_color())  # 生成一个图片对象

3. ImageDraw

  • 生成一个图像画笔对象

  • 作用: 一般用于在纯色背景图片对象上添加文字,画点或画线等

  • 语法: ImageDraw.Draw(图片对象)

draw_obj = ImageDraw.Draw(img_obj)  # 生成一个图片画笔对象

3. ImageFont

  • 加载字体文件得到一个字体对象

  • 作用: 一般用于在纯色背景图片对象上添加文字

  • 语法: ImageFont.truetype('字体文件路径', 字体大小)  -> ImageFont.truetype('blog/static/font/kumo.ttf', 28)

font_obj = ImageFont.truetype('blog/static/font/kumo.ttf', 28)

4. 在图片对象上添加文字

  • 语法: 图像画笔对象.text(xy=坐标, text='需要添加的文字', fill=RGB色值 或 颜色的英文单词, font=文字对象)
图像画笔对象.text(xy=(0, 0), text='文字', fill=(0, 0, 0), font=font_obj)

from PIL import Image, ImageDraw, ImageFont

img_obj = Image.new('RGB', (245, 34), (255, 255, 0))  # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj)  # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28)  # 加载字体文件得到一个字体对象

draw_obj.text(xy=(0, 0), text='文字', fill=(0, 0, 0), font=font_obj)  # 在图片对象上添加文字

5. 在图片对象上画弧线

  • 语法: 图像画笔对象.arc(xy=(num_x, num_y, num_x2, num_y2), start=num, end=num, fill=RGB色值 或 颜色的英文单词)
图像画笔对象.arc((50, 50, 100, 100), 0, 270, fill=(0, 0, 0))

  • 参数说明:
    • xy 坐标: 需要传递两个点的xy坐标
    • start 和 end: 是确定弧度的值

from PIL import Image, ImageDraw, ImageFont

img_obj = Image.new('RGB', (500, 500), (255, 255, 0))  # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj)  # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28)  # 加载字体文件得到一个字体对象

draw_obj.arc((50, 50, 100, 100), 0, 270, fill=(0, 0, 0))  # 在图片对象上画弧线

6. 在图片对象上画线

  • 语法: 图像画笔对象.line(xy=(num_x, num_y, num_x2, num_y2), fill=RGB色值 或 颜色的英文单词)
图像画笔对象.line((10, 10, 100, 100), fill=(0, 0, 0))

  • 参数说明:
    • xy 坐标: 需要传递两个点的xy坐标,因为两点确定一条直线

from PIL import Image, ImageDraw, ImageFont

img_obj = Image.new('RGB', (500, 500), (255, 255, 0))  # 生成一个图片对象
draw_obj = ImageDraw.Draw(img_obj)  # 生成一个图片画笔对象
font_obj = ImageFont.truetype('static/font/kumo.ttf', 28)  # 加载字体文件得到一个字体对象

draw_obj.line((10, 10, 100, 100), fill=(0, 0, 0))  # 在图片对象上画线

7. 将图片对象保存到文件中或内存中

  • 语法: 图片对象.save(文件句柄, '图片格式')

  • 将图片对象保存到文件中,并且生成一张图片

    • 注意: 使用bytes类型写入,因为将图片发送给浏览器时需要发送bytes类型的数据

from PIL import Image, ImageDraw, ImageFont

image = Image.new('RGB', (245, 34), (255, 255, 0))  # 生成一个图片对象

f = open('valid_code.png', 'wb')
image.save(f, 'png')  # 使用图片对象中的save方法,生成一张图片

f = open('valid_code.png', 'rb')
data = f.read()  # 读取图片

  • 将图片对象保存到内存中

from PIL import Image, ImageDraw, ImageFont
from io import BytesIO

image = Image.new('RGB', (245, 34), (255, 255, 0))  # 生成一个图片对象

io_obj = BytesIO()  # 生成一个内存对象,相当于文件句柄
image.save(io_obj, 'png')  # 将图片保存到内存中

data = io_obj.getvalue()  # 从io对象里面取上一步保存的数据
io_obj.close()  # 关闭

8. Django的相关操作

  • 将通过PIL模块生成的图片发送给浏览器

# views.py

from PIL import Image, ImageDraw, ImageFont
from io import BytesIO


def views_fn(request):
    image = Image.new('RGB', (245, 34), (255, 255, 0))  # 生成一个图片对象

    io_obj = BytesIO()  # 生成一个内存对象,相当于文件句柄
    image.save(io_obj, 'png')  # 将图片保存到内存中

    data = io_obj.getvalue()  # 从io对象里面取上一步保存的数据
    io_obj.close()  # 关闭

    return HttpResponse(data)  # 将bytes类型数据的图片发送给浏览器

9. 生成一个图片验证码

# views.py

import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from django.shortcuts import render, redirect, HttpResponse


def get_vaild_img(request):
# 随机生成RGB色值
    def get_random_color():
        return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

    img_obj = Image.new('RGB', (245, 34), get_random_color())  # 生成一个图片对象
    draw_obj = ImageDraw.Draw(img_obj)  # 生成一个图片画笔对象
    font_obj = ImageFont.truetype('static/font/kumo.ttf', 28)  # 加载字体文件得到一个字体对象

# 生成验证码的随机字符串并且写在图片上
    tmp_list = []
    for i in range(5):
        u = chr(random.randint(65, 90))  # 生成大写字母
        l = chr(random.randint(97, 122))  # 生成小写字母
        n = str(random.randint(0, 9))  # 生成数字,注意要转换成字符串类型

        tmp = random.choice([u, l, n])  # 随机返回一个大小写字母或数字
        tmp_list.append(tmp)
        draw_obj.text((25 + 45 * i, 0), tmp, fill=get_random_color(), font=font_obj)

    request.session['valid_str'] = ''.join(tmp_list)  # 将随机生成的字符串写入session中,用于登陆判断

# 给验证图片添加干扰线
    width = 245  # 图片宽度(防止越界)
    height = 34  # 图片宽度(防止越界)
    for i in range(5):
        x1 = random.randint(0, width)
        x2 = random.randint(0, width)
        y1 = random.randint(0, height)
        y2 = random.randint(0, height)
        draw_obj.line((x1, y1, x2, y2), fill=get_random_color())

# 给验证图片添加干扰点
    for i in range(40):
        draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())

 # 在内存中生成图片
    io_obj = BytesIO()  # 生成一个内存对象,相当于文件句柄
    img_obj.save(io_obj, 'png')
    data = io_obj.getvalue()  # 从io对象里面取上一步保存的数据
    io_obj.close()  # 关闭

    return HttpResponse(data)  # 将bytes类型数据的图片发送给浏览器